gtk/popover: Request fake motion events for popovers too
authorJonas Ådahl <jadahl@gmail.com>
Fri, 4 Dec 2020 08:12:22 +0000 (09:12 +0100)
committerJonas Ådahl <jadahl@gmail.com>
Mon, 7 Dec 2020 19:37:29 +0000 (20:37 +0100)
As with GtkWindow, we need to request fake motion events if allocation
changes, to emulate motion events given the new layout.

gtk/gtkpopover.c

index 21e7f2e7168a494994fb21484e55db32bc6954a6..0aff55995d2dff96b93d4b5c5bb723d176a4ffa4 100644 (file)
@@ -589,6 +589,34 @@ gtk_popover_native_check_resize (GtkNative *native)
     present_popup (popover);
 }
 
+static void
+maybe_request_motion_event (GtkPopover *popover)
+{
+  GtkWidget *widget = GTK_WIDGET (popover);
+  GtkRoot *root = gtk_widget_get_root (widget);
+  GdkSeat *seat;
+  GdkDevice *device;
+  GtkWidget *focus;
+  GdkSurface *focus_surface;
+
+  seat = gdk_display_get_default_seat (gtk_widget_get_display (widget));
+  if (!seat)
+    return;
+
+
+  device = gdk_seat_get_pointer (seat);
+  focus = gtk_window_lookup_pointer_focus_widget (GTK_WINDOW (root),
+                                                  device, NULL);
+  if (!focus)
+    return;
+
+  if (!gtk_widget_is_ancestor (focus, GTK_WIDGET (popover)))
+    return;
+
+  focus_surface = gtk_native_get_surface (gtk_widget_get_native (focus));
+  gdk_surface_request_motion (focus_surface);
+}
+
 static void
 gtk_popover_native_layout (GtkNative *native,
                            int        width,
@@ -601,9 +629,19 @@ gtk_popover_native_layout (GtkNative *native,
   update_popover_layout (popover, gdk_popup_layout_ref (priv->layout));
 
   if (gtk_widget_needs_allocate (widget))
-    gtk_widget_allocate (widget, width, height, -1, NULL);
+    {
+      gtk_widget_allocate (widget, width, height, -1, NULL);
+
+      /* This fake motion event is needed for getting up to date pointer focus
+       * and coordinates when tho pointer didn't move but the layout changed
+       * within the popover.
+       */
+      maybe_request_motion_event (popover);
+    }
   else
-    gtk_widget_ensure_allocate (widget);
+    {
+      gtk_widget_ensure_allocate (widget);
+    }
 }
 
 static gboolean